import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文
# plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
import os
import glob

chinese = 'Source Han Serif CN'
filename = 'plotconfig.txt'
print("\n请修改配置文件" + filename + ",或者删除该文件重新生成！\r\n")
# 每个试样的属性数量
pn = 5
if not os.path.isfile(filename):
    # 试样数量
    snum = input("试样数量:")
    snum = 1 if not snum else int(snum)
    # 图片每行数量
    figlay = 1
    # 数据来源
    num = 0
    files = []
    filen = []
    for file in glob.glob(r'*.xls*'):
        if "~" not in file:
            num += 1
            files.append(file)
    print("\r\n文件数量要与试样数量一致，同一来源请标多次！")
    for i in range(1, num + 1):
        print(str(i) + ":" + files[i - 1])
    filem = input("选择文件(两个文件用逗号隔开,默认1):")
    if not filem:
        filen.append("1")
    else:
        filen = filem.split(',')
    if len(filen) < snum:
        print("\r\n数据来源数量不对！退出程序！")
        os._exit(0)
    # print(files[int(filen[0])-1])

    # 索引名，即x轴名
    xindex = input('\r\nx轴单位(默认位置(mm)):')
    xindex = "位置(mm)" if not xindex else xindex
    # 设置y轴名称
    ylabel = input("\r\ny轴单位(默认HV0.2):")
    ylabel = "硬度(HV0.2)" if not ylabel else ylabel
    # 坐标轴范围
    initn = 3
    xfe = input('\r\nx轴范围(头尾用逗号隔开，默认自动):')
    xfe = 0 if not xfe else list(map(float, xfe.split(',')))
    initn += 1 if not xfe else initn
    yfe = input('\r\ny轴范围(头尾用逗号隔开，默认自动):')
    yfe = 0 if not yfe else list(map(float, yfe.split(',')))
    initn += 1 if not yfe else initn
    with open(filename, 'w+') as f:
        f.write("试样数量:" + str(snum))
        f.write("\r每行的图数量:" + str(figlay))
        f.write("\rx轴:" + xindex)
        f.write("\ry轴:" + ylabel)
        if xfe != 0:
            f.write("\rx轴范围:" + str(xfe)[1:-1])
        if yfe != 0:
            f.write("\ry轴范围:" + str(yfe)[1:-1])

    for i in range(1, snum + 1):
        sa = input("\r\n第" + str(i) + "个试样编号:")
        sa = "sample" + str(i) if not sa else sa
        # 数据列
        print("------x轴数据列在excel前列------")
        datat = input("第" + str(i) + "个图数据列(两列用逗号隔开，连续列则使用首尾列再用冒号隔开),默认A,B:")
        datat = "A,B" if not datat else datat
        # excel参数
        sheetn = input('请输入excel的表单序号，默认0,表示sheet1:')
        sheetn = 0 if not sheetn else int(sheetn)
        srows = input('请输入跳过的行数，默认0不跳行:')
        srows = 0 if not srows else int(srows)
        with open(filename, 'a+') as f:
            f.write("\r\n试样编号:" + sa)
            f.write("\r来源文件名(excel):" + files[int(filen[i - 1]) - 1])
            f.write("\r数据列:" + datat)
            f.write("\r表单号:" + str(sheetn))
            f.write("\r跳过行数:" + str(srows))

config = pd.read_csv('plotconfig.txt',
                     sep=':',
                     index_col=0,
                     header=None,
                     encoding='gbk')
listall = []
if '范围' in config.index[5]:
    initn = 6
elif '范围' in config.index[4]:
    initn = 5
else:
    initn = 4
# sheet_name=0表示读取sheet1数据，skiprows=2跳过前两行，header=None表示读取的第一行不作为列的名称
# index_col=0表示选取第一列作为行标签，usecols=[0,1]读取第一、二列数据,names设置每列的名字，包括索引列
# list的写法，小的数在前，index_col是指读进去后的第几列做为index,后边的names顺序与usecols对应
for i in range(0, int(config.iloc[0][1])):
    a = pd.read_excel(
        config.iloc[i * pn + initn + 1][1],
        engine="openpyxl",
        sheet_name=int(config.iloc[i * pn + initn + 3][1]),
        skiprows=int(config.iloc[i * pn + initn + 4][1]),
        header=None,
        usecols=config.iloc[i * pn + initn + 2][1],
        index_col=0,
        names=[config.iloc[1][1], config.iloc[i * pn + initn][1]])
    # 剔除索引或数据有NAN的行(实际就是不是我们的数据)，如果开头有类似数据的索引和数据行，请在读取时使用skiprows剔除
    a = a.loc[a.dropna().index.dropna()]
    listall.append(a)

# 数据对齐处理,并将图形对称到y轴附近
maxdata = []
for i in range(len(listall)):
    data = listall[i]
    # 定义行数,0表示首行
    data['key'] = np.arange(len(data))
    # print(data.columns[0])
    # 创建一个dataframe
    data['pct'] = data[data.columns[0]].pct_change()
    # 计算波浪起止点，行数及对应的index
    xs = data[data.pct == data.pct.max()].key.values[0] - 1
    xe = data[data.pct == data.pct.min()].key.values[0]
    # print(xs,xe)
    # 行数操作时，让一个点位于原点，不一定是对称的。
    datamean = int((xe + xs) / 2)
    # print(datamean)
    x0 = data[data.key == datamean].index[0]  # 转换成numerical，供后面的广播减法
    # print(x0)
    # 去除pct_change、key列，方便后面作图
    data.drop(['pct', 'key'], axis=1, inplace=True)
    listall[i] = data.set_index(data.index - x0)
    # 最大值定位
    ymax = listall[i].max()[0]
    yindex = listall[i][listall[i][listall[i].columns[0]] == ymax].index[0]
    maxdata.append([yindex, ymax])

# color=['#ff5384','#4456c7','#b5a6b7','#ff80a0','green','yellow','black','red','white']
# color=['#ffc900','#595959','#fe8c00','#ff5338','green','yellow','black','red','white']
# color=['#37a2da','#67e0e3','#ffdb5c','#ff9f7f','#e062ae','#ea6a6a','#97c979','#fb8d34','#feebae','#fdcf84','#48b788','#9f4ef4','#7894ea']
color = [
    '#4f81bd', '#c0504d', '#9bbb59', '#8064a2', '#4bacc6', 'yellow', 'black',
    'red', 'orange', 'blue'
]
marker = [
    '.', ',', 's', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', 'p', '*', 'h',
    'H', '+', 'x', 'D', 'd', '|', '_'
]
tlabel = []
print(len(listall))
for i in range(len(listall)):
    plt.plot(listall[i], color=color[i], marker=marker[i + 2])
    tlabel.append(listall[i].columns[0])
# 图例内容使用元组模式，并在元素后面加上逗号，避免显示不全,loc=1表示在右上角，无此参数则是自动
plt.legend(tlabel, loc=0, prop={"family": chinese})
# plt.plot(b,color='magenta',linestyle='-',Marker='^')
# plt.plot(b,'m^-')
# 各个地方设置中文的方法不一样
# 限制横坐标在x0到xn之间
# 判断是否修改坐标轴
if '范围' in config.index[4]:
    xyin = config.iloc[4][1].split(',')
    xyin = list(map(float, xyin))
    if 'y轴' in config.index[5]:
        yin = config.iloc[5][1].split(',')
        yin = list(map(float, yin))
        plt.ylim(yin[0], yin[1])
    if 'x轴' in config.index[4]:
        plt.xlim(xyin[0], xyin[1])
    else:
        plt.ylim(xyin[0], xyin[1])
# 刻度字体大小
plt.tick_params(labelsize=8)
# plt.title(title,fontproperties=chinese)
plt.xlabel(config.iloc[2][1], fontproperties=chinese)
plt.ylabel(config.iloc[3][1], fontproperties=chinese)
# 打开次刻度
plt.minorticks_on()
# 网格线
plt.grid(which='major', color='k', linestyle='-', linewidth=1, alpha=0.3)
plt.grid(which='minor', color='gray', linestyle='--', linewidth=1, alpha=0.3)
# j=0
# # 注解最大值
# for x,y in maxdata:
#     # 注释相对注释点的位置
#     j=j+1
#     zs=input("\r\n第"+str(j)+"幅图注释位置相对于要注释点的坐标(非0)(默认+30,-30):")
#     zs=[+30,-30] if not zs else list(map(float,zs.split(',')))
#     plt.annotate(y,xy=(x,y),xytext=(zs[0],zs[1]),textcoords='offset points',
#     	fontsize=8,arrowprops=dict(facecolor='black',
#     		headwidth=4,width=0.1,alpha=0.7))
# # 画最大值的水平线
# y=ymax+a.index*0
# plt.plot(y,color='pink',linestyle='--',alpha=1)
# 画竖直线vlines(x,ymin.ymax),水平用hlines
# plt.vlines(1,0,maxdata[0][1],color='red',linestyle='--')
# # 获取当前axes
# ax=plt.gca()
# # 隐藏上面和右边的坐标轴
# ax.spines['right'].set_color('none')
# ax.spines['top'].set_color('none')

# 调整图片间距，默认(左left，下bottom，右right，上top，水平间距wspace，竖直间距hspace)(0.125,0.1,0.9,0.9,0.2,0.2)
# plt.subplots_adjust(left=0.15)

plt.savefig(config.iloc[3][1] + ".png", dpi=140,
            bbox_inches='tight')  # dpi越大图越清晰
plt.show()

# 一些方法
# a.size #获取行数
# a.values[0][0] #获取第一行第一列数据
# a.index.values[0] #索引第一个的值
# a.columns[0] #第一列的列索引名
# 获取dataframe列构成ndarray,a['1#'].values[1:]
# 获取一个Series：  a['1#'][1：]
# dataframe添加列时，使用series添加，索引用原来的索引，series可以值得数量不足
# a['diff']=pd.Series((a['1#'].values[1:]-a['1#'].values[:-1])/(a.index[1]-a.index[0]),index=a.index[1:])

# xs=a.loc[abs(a['diff'])>100].index[0]-(a.index[1]-a.index[0])

# xe=a.loc[abs(a['diff'])>100].index[-1]
